from typing import List

from app.crud.simulation_result_total import generate_24_hour_datetime_list
from app.models.electric_price_info import ElectricPriceInfo
from app.models.electric_price_value import ElectricPriceValue
from app.schemas.electric_price_info import ElectricPriceInfoCreate, ElectricPriceInfoCreateList, \
    ElectricPriceValueCreate
from tortoise.transactions import in_transaction

async def create_price_info(data: ElectricPriceInfoCreate) -> bool:
    """
    创建电价信息，并批量创建关联的电价数值。
    :param data: ElectricPriceInfoCreate 实例，含基础字段和多个电价数值
    :return: bool 创建是否成功
    """
    if len(data.values) != data.granularity:
        # 也可以抛异常，视调用端需求而定
        return False

    async with in_transaction() as connection:
        # 先创建电价信息主表
        price_info = await ElectricPriceInfo.create(
            period_unit=data.period_unit,
            period=data.period,
            price_type=data.price_type,
            granularity=data.granularity,
            price_name=data.price_name,
            using_db=connection,
            icon=data.icon
        )

        # 创建关联的电价数值记录，批量插入
        price_values = [
            ElectricPriceValue(
                price_id=price_info.price_id,
                time_point=val.time_point,
                price_amount=val.price_amount
            ) for val in data.values
        ]
        await ElectricPriceValue.bulk_create(price_values, using_db=connection)

    return True


async def delete_price_info(price_id: int) -> bool:
    """
    根据 price_id 删除电价信息记录及其关联的电价数值。
    :param price_id: 电价信息的主键 ID
    :return: 是否删除成功
    """
    async with in_transaction() as conn:
        # 先删除子表
        await ElectricPriceValue.filter(price_id=price_id).using_db(conn).delete()

        # 再删除主表
        deleted_count = await ElectricPriceInfo.filter(price_id=price_id).using_db(conn).delete()

        return deleted_count > 0

async def list_price_info() -> list[ElectricPriceInfo]:
    return await ElectricPriceInfo.all()

async def list_price_values_by_price_id(price_id: int) -> dict:
    """
    获取指定 price_id 的电价时间点列表和电价数值列表。
    :return: dict，包含 time_list 和 value_list
    """
    records = await ElectricPriceValue.filter(price_id=price_id).order_by("time_point")
    time_list = [r.time_point for r in records]
    value_list = [float(r.price_amount) for r in records]
    return {
        "time_list": time_list,
        "value_list": value_list
    }


def list_parameters_by_category(price_type):
    return ElectricPriceInfo.filter(price_type=price_type)


async def delete_price_infos(price_ids: List[int]) -> int:
    # 先删除关联的电价数值记录
    await ElectricPriceValue.filter(price_id__in=price_ids).delete()
    # 再删除主表记录
    deleted_count = await ElectricPriceInfo.filter(price_id__in=price_ids).delete()
    return deleted_count


async def list_prices_detail_by_ids(price_ids):
    pricess = await ElectricPriceInfo.filter(price_id__in=price_ids).prefetch_related('price_values')

    result = []
    for price in pricess:
        time_list = []
        value_list = []
        for pv in price.price_values:
            time_list.append(pv.time_point)
            value_list.append(float(pv.price_amount))

        result.append({
            "price_id": price.price_id,
            "icon": price.icon,
            "period_unit": price.period_unit,
            "period": price.period,
            "granularity": price.granularity,
            "price_name": price.price_name,
            "background": price.background,
            "time_list": time_list,
            "value_list": value_list,
            "price_type": price.price_type
        })

    class Config:
        from_attributes = True

    return result

async def create_price_info_list(data: ElectricPriceInfoCreateList):
    data_time = generate_24_hour_datetime_list()
    values = []
    for index,item in enumerate(data.values):
        values.append(
            ElectricPriceValueCreate(
            time_point=data_time[index],
            price_amount=item
        ))

    data_info = ElectricPriceInfoCreate(
        period_unit=data.period_unit,
        period=data.period,
        price_type=data.price_type,
        granularity=data.granularity,
        price_name=data.price_name,
        icon=data.icon,
        values=values
    )

    return await create_price_info(data_info)